#pragma once
#include <QString>
#include <QIcon>
#include <QUuid>
#include <QDateTime>
#include <QPixmap>
#include <QFileInfo>
#include <QDebug>

#include "../utils/log.hpp"
#include "../utils/widgetuitl.hpp"
#include "base.qpb.h"

namespace model {

/////////// 用户信息
class UserInfo
{
public:
    QString userId = "";
    QString nickname = "";       // 昵称
    QString description = "";    // 个签
    QString phone = "";
    QIcon avatar;                // 头像

    void load(const im_proto::UserInfo& userInfo)
    {
        userId = userInfo.userId();
        nickname = userInfo.nickname();
        description = userInfo.description();
        phone = userInfo.phone();
        avatar = userInfo.avatar().isEmpty() ? QIcon(":/resource/image/defaultAvatar.png") : utils::WidgetUtil::makeIcon(userInfo.avatar());
    }
};

enum MessageType {
    TEXT_TYPE,      // 文本消息
    IMAGE_TYPE,     // 图片消息
    FILE_TYPE,      // 文件消息
    SPEECH_TYPE,    // 语音消息
    UNKNOWN_TYPE    // 错误类型
};


/////////// 消息信息
class Message
{
public:
    QString messageId = "";
    QString charSessionId = "";          // 消息所属会话
    UserInfo sender;                     // 发送方
    QString time = "";                   // 发送时间, 形如 07-13 14:30
    MessageType messageType = MessageType::TEXT_TYPE;   // 消息类型
    QByteArray content;                  // 消息正文
    QString fileId = "";                 // 非文件数据该字段为 null
    QString fileName = "";               // 文件消息特有

    static QString makeId()
    {
        // 简化视觉, 只取最后一段
        return "M" + QUuid::createUuid().toString().sliced(25, 12);
    }

    static Message makeMessage(MessageType messageType, const QString& chatSessionId, const UserInfo& sender, const QByteArray& content, const QString& filenName = "")
    {
        if (messageType == MessageType::TEXT_TYPE) {
            return makeTextMessage(chatSessionId, sender, content);
        } else if (messageType == MessageType::SPEECH_TYPE) {
            return makeSpeechMessage(chatSessionId, sender, content);
        } else if (messageType == MessageType::IMAGE_TYPE) {
            return makeImageMessage(chatSessionId, sender, content);
        } else if (messageType == MessageType::FILE_TYPE) {
            return makeFileMessage(chatSessionId, sender, content, filenName);
        } else {
            return Message();
        }
    }

    void load(const im_proto::MessageInfo& messageInfo)
    {
        messageId = messageInfo.messageId();
        charSessionId = messageInfo.chatSessionId();
        sender.load(messageInfo.sender());
        time = utils::TimeUtil::formatTime(messageInfo.timestamp());

        auto type = messageInfo.message().messageType();
        if(type == im_proto::MessageTypeGadget::MessageType::STRING) {
            messageType = MessageType::TEXT_TYPE;
            content = messageInfo.message().stringMessage().content().toUtf8();
        } else if(type == im_proto::MessageTypeGadget::MessageType::IMAGE) {
            messageType = MessageType::IMAGE_TYPE;
            if(messageInfo.message().imageMessage().hasImageContent()) {
                content = messageInfo.message().imageMessage().imageContent();
            }
            if(messageInfo.message().imageMessage().hasFileId()) {
                fileId = messageInfo.message().imageMessage().fileId();
            }
        } else if(type == im_proto::MessageTypeGadget::MessageType::FILE) {
            messageType = MessageType::FILE_TYPE;
            if(messageInfo.message().fileMessage().hasFileContents()) {
                content = messageInfo.message().fileMessage().fileContents();
            }
            if(messageInfo.message().fileMessage().hasFileId()) {
                fileId = messageInfo.message().fileMessage().fileId();
            }
            fileName = messageInfo.message().fileMessage().fileName();
        } else if(type == im_proto::MessageTypeGadget::MessageType::SPEECH) {
            messageType = MessageType::SPEECH_TYPE;
            if(messageInfo.message().speechMessage().hasFileContents()) {
                content = messageInfo.message().speechMessage().fileContents();
            }
            if(messageInfo.message().speechMessage().hasFileId()) {
                fileId = messageInfo.message().speechMessage().fileId();
            }
        } else {
            LOG(LL_WARN, "非法的消息类型: {}", type);
        }
    }

private:
    static Message makeTextMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.messageId = makeId();
        message.charSessionId = chatSessionId;
        message.sender = sender;
        message.time = utils::TimeUtil::formatTime(utils::TimeUtil::getNowTime());
        message.messageType = MessageType::TEXT_TYPE;
        message.content = content;
        return message;
    }
    static Message makeSpeechMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.messageId = makeId();
        message.charSessionId = chatSessionId;
        message.sender = sender;
        message.time = utils::TimeUtil::formatTime(utils::TimeUtil::getNowTime());
        message.messageType = MessageType::SPEECH_TYPE;
        message.content = content;
        return message;
    }
    static Message makeImageMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.messageId = makeId();
        message.charSessionId = chatSessionId;
        message.sender = sender;
        message.time = utils::TimeUtil::formatTime(utils::TimeUtil::getNowTime());
        message.messageType = MessageType::IMAGE_TYPE;
        message.content = content;
        return message;
    }
    static Message makeFileMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content,  const QString& filenName)
    {
        Message message;
        message.messageId = makeId();
        message.charSessionId = chatSessionId;
        message.sender = sender;
        message.time = utils::TimeUtil::formatTime(utils::TimeUtil::getNowTime());
        message.messageType = MessageType::FILE_TYPE;
        message.content = content;
        message.fileName = filenName;
        return message;
    }
};


/////////// 聊天会话信息
class ChatSessionInfo
{
public:
    QString chatSessionId = "";
    QString chatSessionName = "";    // 会话昵称（单聊or群名）
    Message lastMessage;             // 会话界面预览的最新消息
    QIcon avatar;                    // 会话头像
    QString userId = "";             // 单聊时为对方id, 群聊为""

    void load(const im_proto::ChatSessionInfo& chatSessionInfo)
    {
        chatSessionId = chatSessionInfo.chatSessionId();
        chatSessionName = chatSessionInfo.chatSessionName();
        if(chatSessionInfo.hasSingleChatFriendId()) {
            userId = chatSessionInfo.singleChatFriendId();
        }
        if(chatSessionInfo.hasPrevMessage()) {
            lastMessage.load(chatSessionInfo.prevMessage());
        }
        if(chatSessionInfo.hasAvatar() && !chatSessionInfo.avatar().isEmpty()) {
            avatar = utils::WidgetUtil::makeIcon(chatSessionInfo.avatar());
        } else {
            if(userId != "") {
                avatar = QIcon(":/resource/image/defaultAvatar.png");
            } else {
                avatar = QIcon(":/resource/image/groupAvatar.png");
            }
        }
    }
};



}
